package com.youlu.campus.domain.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.youlu.campus.common.exception.BusinessException;
import com.youlu.campus.common.utils.RedisKeyUtil;
import com.youlu.campus.domain.entity.PlatformDomainConfig;
import com.youlu.campus.domain.entity.PlatformDomainConfigPageQuery;
import com.youlu.campus.domain.repositories.PlatformDomainConfigRepository;
import com.youlu.campus.domain.service.PlatformDomainConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 域名配置服务层
 *
 * @Description: DomainConfigService
 * @Date 2025/10/21
 * @module DomainConfig
 * @author: su
 */
@Slf4j
@Service
public class PlatformDomainConfigServiceImpl implements PlatformDomainConfigService {

    @Autowired
    private PlatformDomainConfigRepository domainConfigRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public PlatformDomainConfig findById(String id) {
        Optional<PlatformDomainConfig> optional = domainConfigRepository.findById(id);
        return optional.orElse(null);
    }

    @Override
    public PlatformDomainConfig findByDomain(String domain) {
        String key = RedisKeyUtil.getPlatformDomainConfigKey(domain);
        String s = redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotBlank(s)) {
            return JSONObject.parseObject(s, PlatformDomainConfig.class);
        }
        PlatformDomainConfig domainConfig = domainConfigRepository.findByDomain(domain);
        redisTemplate.opsForValue().set(key, JSONObject.toJSONString(domainConfig), 3, TimeUnit.DAYS);
        return domainConfig;
    }

    @Override
    public Page<PlatformDomainConfig> findByPage(PlatformDomainConfigPageQuery pageQuery) {
        Query query = new Query();
        if (StringUtils.isNotBlank(pageQuery.getDomain())) {
            query.addCriteria(Criteria.where("domain").regex(pageQuery.getDomain(), "i"));
        }
        //统计总条数（分页需要先查总数）
        long total = mongoTemplate.count(query, PlatformDomainConfig.class);

        Pageable pageRequest = PageRequest.of(pageQuery.getPage() - 1, pageQuery.getPageSize(), Sort.by("createTime").descending());
        List<PlatformDomainConfig> list;
        if (total == 0) {
            list = Arrays.asList();
        } else {
            // 应用分页（设置跳过的条数和查询的条数）
            query.skip(pageRequest.getOffset()).limit(pageRequest.getPageSize());
            // 应用排序
            query.with(pageRequest.getSort());
            list = mongoTemplate.find(query, PlatformDomainConfig.class);
        }
        return PageableExecutionUtils.getPage(list, pageRequest, () -> total);
    }

    @Override
    public void delete(String id) {
        deleteRedisById(id);
        domainConfigRepository.deleteById(id);
    }

    /**
     * 创建域名配置
     *
     * @param domainConfig 域名配置
     * @return 保存后的配置
     */
    public PlatformDomainConfig save(PlatformDomainConfig domainConfig) {
        // 设置创建时间和更新时间
        PlatformDomainConfig oldDomainConfig = domainConfigRepository.findByDomain(domainConfig.getDomain());
        if (Objects.nonNull(oldDomainConfig) && !oldDomainConfig.getId().equals(domainConfig.getId())) {
            throw new BusinessException("域名已存在: " + domainConfig.getDomain());
        }
        LocalDateTime now = LocalDateTime.now();
        if (StringUtils.isEmpty(domainConfig.getId())) {
            domainConfig.setCreateTime(now);
        } else {
            //删除缓存
            deleteRedisById(domainConfig.getId());
        }
        domainConfig.setIcpFilingInfo(domainConfig.getRecordImg());
        domainConfig.setUpdateTime(now);
        PlatformDomainConfig save = domainConfigRepository.save(domainConfig);
        //删除缓存
        deleteRedisById(save.getId());
        return save;
    }

    /**
     * 检查域名是否存在
     *
     * @param domain 域名
     * @return 是否存在
     */
    @Override
    public boolean isDomainExists(String domain) {
        return domainConfigRepository.existsByDomain(domain);
    }

    /**
     * 删除redis 缓存
     *
     * @param id
     */
    private void deleteRedisById(String id) {
        Optional<PlatformDomainConfig> optional = domainConfigRepository.findById(id);
        if (optional.isPresent()) {
            String domain = optional.get().getDomain();
            String key = RedisKeyUtil.getPlatformDomainConfigKey(domain);
            redisTemplate.delete(key);
        }
    }
}